<template>
  <el-select
    v-model="selectedLabel"
    :placeholder="placeholder"
    :disabled="disabled"
    clearable
    @clear="handleClear"
  >
    <!-- 自定义下拉内容 -->
    <el-option
      :value="selectedValue"
      class="tree-select-option"
    >
      <el-tree
        ref="treeRef"
        :data="treeData"
        :props="treeProps"
        :node-key="nodeKey"
        :default-expanded-keys="defaultExpandedKeys"
        :check-strictly="checkStrictly"
        :show-checkbox="multiple"
        :check-on-click-node="!multiple"
        :default-checked-keys="selectedValue"
        @check="handleCheck"
        @node-click="handleNodeClick"
      />
    </el-option>
  </el-select>
</template>

<script setup>
import { ref, watch, computed } from 'vue'
import { ElTree, ElSelect, ElOption } from 'element-plus'

// 接收外部参数
const props = defineProps({
  // 绑定值（支持单个值或数组，取决于是否多选）
  modelValue: {
    type: [String, Number, Array],
    default: () => multiple ? [] : null
  },
  // 树形数据
  treeData: {
    type: Array,
    default: () => []
  },
  // 树形配置项（同 el-tree 的 props）
  treeProps: {
    type: Object,
    default: () => ({
      label: 'label',
      children: 'children'
    })
  },
  // 节点唯一标识字段
  nodeKey: {
    type: String,
    default: 'id'
  },
  // 是否多选
  multiple: {
    type: Boolean,
    default: false
  },
  // 是否严格遵循父子不互相关联
  checkStrictly: {
    type: Boolean,
    default: false
  },
  // 默认展开的节点
  defaultExpandedKeys: {
    type: Array,
    default: () => []
  },
  // 占位符
  placeholder: {
    type: String,
    default: '请选择'
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  }
})

// 对外暴露事件
const emit = defineEmits(['update:modelValue', 'change', 'clear'])

// 内部状态
const treeRef = ref(null)
const selectedValue = ref(props.modelValue) // 实际选中的值（ID）
const selectedLabel = ref('') // 显示的文本（标签）

// 监听外部传入的 modelValue 变化
watch(
  () => props.modelValue,
  (newVal) => {
    selectedValue.value = newVal
    updateDisplayLabel() // 更新显示文本
  },
  { deep: true }
)

// 处理单选点击节点
const handleNodeClick = (data) => {
  if (props.multiple) return // 多选不处理点击事件
  
  selectedValue.value = data[props.nodeKey]
  emit('update:modelValue', selectedValue.value)
  emit('change', selectedValue.value, data)
  
  // 关闭下拉面板（通过更新选择器值触发）
  selectedLabel.value = data[props.treeProps.label]
}

// 处理多选勾选事件
const handleCheck = (data, checkedInfo) => {
  if (!props.multiple) return // 单选不处理勾选事件
  
  selectedValue.value = checkedInfo.checkedKeys
  emit('update:modelValue', selectedValue.value)
  emit('change', selectedValue.value, checkedInfo)
  
  updateDisplayLabel() // 更新显示文本
}

// 清空选择
const handleClear = () => {
  selectedValue.value = props.multiple ? [] : null
  emit('update:modelValue', selectedValue.value)
  emit('clear')
  
  // 清空树形组件的选中状态
  if (treeRef.value) {
    treeRef.value.setCheckedKeys([])
  }
}

// 更新显示的标签文本
const updateDisplayLabel = () => {
  if (!selectedValue.value || (Array.isArray(selectedValue.value) && selectedValue.value.length === 0)) {
    selectedLabel.value = ''
    return
  }

  // 递归查找节点标签
  const findLabels = (nodes, keys, labels = []) => {
    for (const node of nodes) {
      if (keys.includes(node[props.nodeKey])) {
        labels.push(node[props.treeProps.label])
      }
      if (node[props.treeProps.children] && node[props.treeProps.children].length) {
        findLabels(node[props.treeProps.children], keys, labels)
      }
    }
    return labels
  }

  const keys = Array.isArray(selectedValue.value) ? selectedValue.value : [selectedValue.value]
  const labels = findLabels(props.treeData, keys)
  
  selectedLabel.value = labels.join(', ')
}

// 初始化时更新显示文本
updateDisplayLabel()
</script>

<style scoped lang="scss">
/* 调整下拉面板宽度与树形组件样式 */
.tree-select-option {
  padding: 0;
  .el-tree {
    width: 100%;
    min-width: 200px;
    max-height: 300px;
    overflow-y: auto;
    padding: 10px 0;
  }
}
</style>
